package org.space.galaxyCabinet;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.space.galaxyCabinet.callback.OnMessageCallback;
import org.space.galaxyCabinet.config.EmqxProperties;
import org.space.galaxyCabinet.constant.EmqxConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

/**
 * https://docs.emqx.com/zh/emqx/v5.0/connect-emqx/java.html
 */
@Slf4j
@Component
public class EmqxClientWrapper {

    @Autowired
    private EmqxProperties emqxProperties;

    private MqttClient client;

    @Autowired
    private OnMessageCallback onMessageCallback;

    @PostConstruct
    private void init() {
        MqttClientPersistence mqttClientPersistence = new MemoryPersistence();
        try {
            //新建客户端 参数：MQTT服务的地址，客户端名称，持久化
            client = new MqttClient(emqxProperties.getServerURI(), emqxProperties.getClientId(), mqttClientPersistence);

            // 设置回调
            client.setCallback(onMessageCallback);

            // 建立连接
            connect();

        } catch (MqttException e) {
            log.info("MqttClient创建失败");
            throw new RuntimeException(e);
        }
    }
    /**
     * 发布保留消息
     * @param topic 消息主题
     * @param data 消息内容
     */
    public void publishRetainedMessage(String topic, String data) {
        try {
            MqttMessage message = new MqttMessage(data.getBytes());
            message.setQos(2); // 设置QoS等级为2，确保消息可靠传输
            message.setRetained(true); // 设置为保留消息
            client.publish(topic, message);
            log.info("保留消息发布成功，主题：{}，内容：{}", topic, data);
        } catch (MqttException e) {
            log.error("保留消息发布失败", e);
        }
    }

    /**
     * 删除保留消息
     * @param topic 消息主题
     */
    public void deleteRetainedMessage(String topic) {
        try {
            // 发布一条空消息作为保留消息，覆盖原来的保留消息
            MqttMessage message = new MqttMessage("".getBytes());
            message.setQos(2); // 设置QoS等级为2，确保消息可靠传输
            message.setRetained(true); // 设置为保留消息
            client.publish(topic, message);
            log.info("保留消息删除成功，主题：{}", topic);
        } catch (MqttException e) {
            log.error("保留消息删除失败", e);
        }
    }

    public Boolean connect() {
        // 设置连接的配置
        try {
            client.connect(mqttConnectOptions());
            log.info("连接成功");

            // 订阅
            client.subscribe(EmqxConstants.getAll());
            return true;
        } catch (MqttException e) {
            log.info("连接失败");
            e.printStackTrace();
        }
        return false;
    }

    /*创建MQTT配置类*/
    private MqttConnectOptions mqttConnectOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(emqxProperties.getUsername());
        options.setPassword(emqxProperties.getPassword().toCharArray());
        options.setAutomaticReconnect(true);//是否自动重新连接
        options.setCleanSession(true);//是否清除之前的连接信息
        options.setConnectionTimeout(emqxProperties.getConnectionTimeout());//连接超时时间
        options.setKeepAliveInterval(emqxProperties.getKeepAliveInterval());//心跳
        return options;
    }

    public boolean delete() {
        String managementApiUrl = emqxProperties.getServerURI();

        try {
            // 创建 HTTP 客户端
            HttpClient client = HttpClient.newHttpClient();

            // 构建请求来清理延迟消息
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(managementApiUrl + "?topic=test/topic"))
                .header("Content-Type", "application/json")
                .DELETE() // 使用 DELETE 方法清理消息
                .build();

            // 发送请求
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            // 检查响应
            System.out.println("Status: " + response.statusCode());
            System.out.println("Response: " + response.body());

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 发布消息
     * @param topic
     * @param data
     */
    public void publish(String topic, String data) {
        try {
            MqttMessage message = new MqttMessage(data.getBytes());
            message.setQos(2);
            client.publish(topic, message);
        } catch (MqttException e) {
            log.info("消息发布失败");
            e.printStackTrace();
        }
    }

}
